package com.g0dkar.leet.util.reflection;

import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;

import com.g0dkar.leet.util.common.StringUtils;

class FieldsNamesCollector implements ClassVisitor {
	
	private Set<String> properties = new LinkedHashSet<String>();
	private Map<String, String> propertiesMethod = new LinkedHashMap<String, String>();
	
	public void visit(int arg0, int arg1, String arg2, String arg3, String arg4, String[] arg5) {
	}
	
	public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) {
		return null;
	}
	
	public void visitAttribute(Attribute arg0) {
	}
	
	public void visitEnd() {
	}
	
	public FieldVisitor visitField(int arg0, String name, String arg2, String arg3, Object arg4) {
		properties.add(name);
		return null;
	}
	
	public void visitInnerClass(String arg0, String arg1, String arg2, int arg3) {
	}
	
	public MethodVisitor visitMethod(int arg0, String name, String arg2, String arg3, String[] arg4) {
		String[] argsMethod = {};
		String typeReturn = "";
		
		if (arg2 != null) {
//			String substringArgs = org.apache.commons.lang.StringUtils.substringBetween(arg2, "(", ")").trim();
//			if (!StringUtils.isEmpty(substringArgs)) {
//				argsMethod = substringArgs.split(";");
//			}
//			typeReturn = org.apache.commons.lang.StringUtils.substringAfterLast(arg2, ")").replace(";", "");
		}
		
		if (name.startsWith("get") || name.startsWith("is")) {
			if (argsMethod.length == 0 && !typeReturn.equals("V")) {
				String fieldName = StringUtils.asField(name);
				if (propertiesMethod.containsKey(fieldName) && propertiesMethod.get(fieldName).equals(typeReturn)) {
					properties.add(fieldName);
					
				}
				else {
					propertiesMethod.put(fieldName, typeReturn);
				}
			}
			
		}
		else if (name.startsWith("set")) {
			if (argsMethod.length == 1 && typeReturn.equals("V")) {
				String fieldName = StringUtils.asField(name);
				if (propertiesMethod.containsKey(fieldName) && propertiesMethod.get(fieldName).equals(argsMethod[0])) {
					properties.add(fieldName);
					
				}
				else {
					propertiesMethod.put(fieldName, argsMethod[0]);
				}
			}
		}
		
		return null;
	}
	
	public void visitOuterClass(String arg0, String arg1, String arg2) {
	}
	
	public void visitSource(String arg0, String arg1) {
	}
	
	public Set<String> getFieldsNames() {
		return properties;
	}
	
}
